Skip to content

Version 5.0: Major change from CRA to Vite and TypeScript with Google Civic Info API Representatives replacement#162

Merged
jungshadow merged 15 commits into
mainfrom
feature/major-upgrade
May 20, 2026
Merged

Version 5.0: Major change from CRA to Vite and TypeScript with Google Civic Info API Representatives replacement#162
jungshadow merged 15 commits into
mainfrom
feature/major-upgrade

Conversation

@jungshadow
Copy link
Copy Markdown
Owner

@jungshadow jungshadow commented May 13, 2026

Version 5.0

  • CRA -> Vite 8 with @vitejs/plugin-react
  • React 16 -> 19 with react-dom/client (createRoot)
  • react-router-dom v7NavLink className function API, no activeClassName
  • pnpm as sole package manager (packageManager field enforced)
  • Replace lodash with native JS, moment.js with date-fns
  • Replace node-sass with sass (Dart Sass)
  • framer-motion upgraded — removed deprecated layoutTransition prop
  • Every .js/.jsx file converted to .ts/.tsx
  • Strict mode enabled (tsconfig.json with strict: true)
  • Full type definitions for API responses, app state, and actions (src/types/)
  • PropTypes removed entirely — replaced by TypeScript interfaces
  • Path aliases configured in both tsconfig.json and vite.config.js
  • ESLint 9 flat config with typescript-eslint, react-hooks, prettier
  • Prettier 3 with project-wide formatting
  • Fixed all lint errors: hooks ordering, refs-during-render, cascading setState, unescaped entities
  • Replaced Google Civic representatives endpoint with Open States /people.geo
  • Flow: address -> Mapbox geocode -> lat/lng -> Open States -> transform to existing RepresentativesApiResponse shape
  • Fixed ElectionTitle crash on missing election data (new Date('') → Invalid Date)
  • GitHub Actions deploy workflow (workflow_dispatch) — type check → lint → build → deploy to Pages
  • Secret management: dev uses 1Password CLI (op run), prod uses GitHub Secrets
  • Updated .env.example with setup instructions
  • Vitest 4 + jsdom + @testing-library/react + @testing-library/jest-dom
  • 27 unit/component tests: helpers (19), appReducer (5), ElectionTitle (3)
  • Playwright 1.60 with Chromium — simple E2E smoke test (homepage renders logo + search form)
  • MSW installed for future API mocking
  • Scripts: pnpm test:unit, pnpm test:e2e
  • Removed prop-types, @types/prop-types, @types/mapbox-gl, ajv, gh-pages
  • Removed dead privacy.html, predeploy/deploy scripts, browserslist
  • Removed 31 unnecessary import React from 'react' statements
  • Add ElectionPicker to switch between active elections in a state

- Migrate from Create React App to Vite 8
- Upgrade React 16 → 19 (createRoot API)
- Upgrade react-router-dom 5 → 7 (Routes/Navigate)
- Upgrade framer-motion 2 → 12
- Replace moment.js with date-fns
- Replace lodash with native implementations
- Replace require() with ESM imports (Autocomplete)
- Rename all .js → .jsx for Vite OXC parser
- Add defensive guards for API failure handling
- Switch to pnpm, add .npmrc and .node-version
- Begin TypeScript migration: tsconfig, type defs, helpers.ts, analytics.ts
- Replace CRA README with project-specific documentation
- Configure 1Password CLI for secret management
jungshadow and others added 5 commits May 12, 2026 23:00
Replace ElectionSelect dropdown with ElectionPicker component that
shows all upcoming elections grouped by date. When multiple elections
match a voter's state (e.g. Texas Dem/Rep primary runoffs on the same
day), an interstitial picker appears before loading results instead of
silently auto-selecting one.

After choosing an election, the picker persists inline on all results
routes so voters can switch between elections without re-searching.

- Add pendingElections/SET_PENDING_ELECTIONS to state and reducer
- Intercept multi-election case in Search before calling getLocations
- Create ElectionPicker component with grouped date display
- Wire picker into Site (interstitial) and all Results routes (inline)
- Guard Navigate in App.tsx against undefined redirect destination
- Remove unused ElectionSelect component
- Add tests for ElectionPicker and new reducer actions
- Added MemoryRouter to ElectionPicker tests for proper routing context.
- Integrated useNavigate in ElectionPicker and Search components to handle navigation to results.
- Removed the unused useRedirectDestination hook to simplify the codebase.
- Updated .gitignore to exclude .pnpm-store directory.
- Added a max-width of 800px to .site__contentInner when it contains a .locationCard for improved layout.
- Cleaned up whitespace in site.scss for better readability.
- Integrated context-based navigation in the Page component to dynamically determine the back path.
- Added ResultsIndexRedirect to redirect users to the last visited results path.
- Implemented rememberResultsPath and getLastResultsPath functions to manage session storage for results navigation.
- Updated Site component to remember the last results path on route changes.
- Enhanced getResultsRoute helper to include new results pathnames.
Copy link
Copy Markdown
Collaborator

@jajohnso jajohnso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

…destination

refactor: streamline navigation and remove unused hook
@jungshadow jungshadow closed this May 20, 2026
@jungshadow jungshadow reopened this May 20, 2026
@jungshadow jungshadow merged commit 5a598b8 into main May 20, 2026
@jungshadow jungshadow deleted the feature/major-upgrade branch May 20, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants